﻿/**
 * SLURM FRAMEWORK
 * VERSION: Beta 1.0
 * DATE: 2012-06-13
 * AUTHOR: Ezequiel Soler
 * GNU Lesser GPL
 **/
package com.slurm
{
	import flash.display.Sprite;
	import flash.events.Event;
	import com.greensock.*;
	import com.greensock.easing.*;
	import flash.utils.getDefinitionByName;
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.display.MovieClip;
	import flash.text.TextField;

	public class Screen extends Sprite
	{
		public var scriptScreen:XML;
		public var timelineStart:TimelineMax;
		public var timelineEnd:TimelineMax;

		public var idNextScreen:Number;
		public var id:Number;

		public function Screen(script:String)
		{
			scriptScreen = new XML(script);
			if (stage)
			{
				init();
			}
			else
			{
				addEventListener(Event.ADDED_TO_STAGE, init);
			}
		}

		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			trace(scriptScreen.@name+" active.");
			id = Number(scriptScreen.@id);
			if(scriptScreen.texts.text.length() > 0){
				for each (var textData:XML in scriptScreen.texts.text)
				{
					TextField(this.getChildByName(textData. @ name)).text = String(textData[GlobalData.lan]);
				}
			}
			if(scriptScreen.buttonsProp.buttonProp.length() > 0){
				for each (var buttonData:XML in scriptScreen.buttonsProp.buttonProp)
				{
					MovieClip(this.getChildByName(buttonData. @ name)).setProperties(XML(buttonData));
				}
			}
			if (scriptScreen.startanim.object.length() > 0)
			{
				timelineStart = new TimelineMax({onComplete:screenReady,onReverseComplete:destroy,pause:true});
				for each (var objectData:XML in scriptScreen.startanim.object)
				{
					var objectAnim:String = objectData. @ name;
					var destination:String = objectData. @ destination;
					var duration:Number = Number(objectData. @ duration);
					var timeStart:Number = Number(objectData. @ timeStart);
					var multipleObjects:Boolean = false;
					var stagger:Number = Number(objectData. @ stagger);;
					var clip:DisplayObject;
					if (objectAnim.indexOf(",") != -1)
					{
						multipleObjects = true;
						var objectsNameArr = objectAnim.split(",");
						var objectsArr = [];
						for each (var objectName:String in objectsNameArr)
						{
							objectsArr.push(this.getChildByName(objectName));
						}
						clip = objectsArr[0];
					}
					else
					{
						clip = this.getChildByName(objectAnim);
					}
					var param:Object = createObjectParams(Utils.trim(objectData. @ params),clip);
					for each (var filterData:XML in objectData.filter)
					{
						param[filterData. @ type] = addFilters(Utils.trim(filterData. @ params));
					}
					if (destination == "to")
					{
						if (! multipleObjects)
						{
							try
							{
								timelineStart.append( TweenMax.to(clip, duration, param) , timeStart );
							}
							catch (error:Error)
							{
								trace("ERROR #03: Animación entrada: El elemento "+objectAnim+" no existe.");
							}
						}
						else
						{
							try
							{
								timelineStart.insertMultiple( TweenMax.allTo(objectsArr, duration, param, stagger), timeStart);
							}
							catch (error:Error)
							{
								trace("ERROR #04: Animación entrada: Uno o más de los elementos "+objectsArr+" no existe.");
							}
						}
					}
					else
					{
						if (! multipleObjects)
						{
							try
							{
								timelineStart.append( TweenMax.from(clip, duration, param) , timeStart );
							}
							catch (error:Error)
							{
								trace("ERROR #03: Animación entrada: El elemento "+objectAnim+" no existe.");
							}
						}
						else
						{
							try
							{
								timelineStart.insertMultiple( TweenMax.allFrom(objectsArr, duration, param, stagger), timeStart);
							}
							catch (error:Error)
							{
								trace("ERROR #04: Animación entrada: Uno o más de los elementos "+objectsArr+" no existe.");
							}
						}
					}

				}
				timelineStart.play();
			}
			else
			{
				screenReady();
			}
		}

		private function createObjectParams(chart:String,clip:DisplayObject):Object
		{
			var paramsOnject:Object = {};
			var paramsArr:Array = chart.split(",");
			for each (var paramData:String in paramsArr)
			{
				var paramProp:Array = paramData.split(':');
				if (paramProp[0] != "ease")
				{
					switch (paramProp[1])
					{
						case 'top' :
							paramsOnject[paramProp[0]] =  -  clip.height - 15;
							break;
						case 'left' :
							paramsOnject[paramProp[0]] =  -  clip.width - 15;
							break;
						case 'right' :
							paramsOnject[paramProp[0]] = stage.stageWidth + clip.width + 15;
							break;
						case 'bottom' :
							paramsOnject[paramProp[0]] = stage.stageHeight + clip.width + 15;
							break;
						default :
							paramsOnject[paramProp[0]] = Number(paramProp[1]);
							break;
					}
				}
				else
				{
					var easingProp:Array = paramProp[1].split(".");
					switch (easingProp[0])
					{
						case "Elastic" :
							paramsOnject[paramProp[0]] = Elastic[easingProp[1]];
							break;
						case "Back" :
							paramsOnject[paramProp[0]] = Back[easingProp[1]];
							break;
						case "Bounce" :
							paramsOnject[paramProp[0]] = Bounce[easingProp[1]];
							break;
						case "Circ" :
							paramsOnject[paramProp[0]] = Circ[easingProp[1]];
							break;
						case "Cubic" :
							paramsOnject[paramProp[0]] = Cubic[easingProp[1]];
							break;
						case "EaseLookup" :
							paramsOnject[paramProp[0]] = EaseLookup[easingProp[1]];
							break;
						case "Expo" :
							paramsOnject[paramProp[0]] = Expo[easingProp[1]];
							break;
						case "FastEase" :
							paramsOnject[paramProp[0]] = FastEase[easingProp[1]];
							break;
						case "Linear" :
							paramsOnject[paramProp[0]] = Linear[easingProp[1]];
							break;
						case "Quad" :
							paramsOnject[paramProp[0]] = Quad[easingProp[1]];
							break;
						case "Quart" :
							paramsOnject[paramProp[0]] = Quart[easingProp[1]];
							break;
						case "Quint" :
							paramsOnject[paramProp[0]] = Quint[easingProp[1]];
							break;
						case "RoughEase" :
							paramsOnject[paramProp[0]] = RoughEase[easingProp[1]];
							break;
						case "Sine" :
							paramsOnject[paramProp[0]] = Sine[easingProp[1]];
							break;
						case "Strong" :
							paramsOnject[paramProp[0]] = Strong[easingProp[1]];
							break;
					}

				}
			}
			return paramsOnject;
		}

		private function addFilters(param:String):Object
		{
			var paramsFilter:Object = {};
			var parmsFilterArr:Array = param.split(",");

			for each (var paramFilterData:String in parmsFilterArr)
			{
				var paramProp:Array = paramFilterData.split(':');
				paramsFilter[paramProp[0]] = paramProp[1];
			}
			return paramsFilter;
		}

		public function screenReady()
		{

			if (scriptScreen.loops.loop.length() > 0)
			{
				for each (var loopData:XML in scriptScreen.loops.loop)
				{

					var repeatLoop:Number = Number(loopData. @ repeat);
					var repeatDelayLoop:Number = Number(loopData. @ repeatDelay);
					var yoyoLoop:Number = Number(loopData. @ yoyo);
					var delayLoop:Number = Number(loopData. @ delay);

					var timelineLoop:TimelineMax = new TimelineMax({repeat:repeatLoop,delay:delayLoop,repeatDelay:repeatDelayLoop,yoyo:yoyoLoop});
					for each (var objectData:XML in loopData.object)
					{

						var objectAnim:String = objectData. @ name;
						var destination:String = objectData. @ destination;
						var duration:Number = Number(objectData. @ duration);
						var timeStart:Number = Number(objectData. @ timeStart);
						var stagger:Number = Number(objectData. @ stagger);
						var multipleObjects:Boolean = false;
						var clip:DisplayObject;
						if (objectAnim.indexOf(",") != -1)
						{
							multipleObjects = true;
							var objectsNameArr = objectAnim.split(",");
							var objectsArr = [];
							for each (var objectName:String in objectsNameArr)
							{
								objectsArr.push(this.getChildByName(objectName));
							}
							clip = objectsArr[0];
						}
						else
						{
							clip = this.getChildByName(objectAnim);
						}
						var param:Object = createObjectParams(Utils.trim(objectData. @ params),clip);

						for each (var objectFilterData:XML in objectData.filter)
						{
							param[objectFilterData. @ type] = addFilters(Utils.trim(objectFilterData. @ params));
						}

						if (destination == "to")
						{
							if (! multipleObjects)
							{
								try
								{
									timelineLoop.append( TweenMax.to(clip, duration, param) , timeStart );
								}
								catch (error:Error)
								{
									trace("ERROR #03: Loop: El elemento "+objectAnim+" no existe.");
								}
							}
							else
							{
								try
								{
									timelineLoop.insertMultiple( TweenMax.allTo(objectsArr, duration, param, stagger), timeStart);
								}
								catch (error:Error)
								{
									trace("ERROR #04: Loop: Uno o más de los elementos "+objectsArr+" no existe.");
								}
							}
						}
						else
						{
							if (! multipleObjects)
							{
								try
								{
									timelineLoop.append( TweenMax.from(clip, duration, param) , timeStart );
								}
								catch (error:Error)
								{
									trace("ERROR #03: Loop: El elemento "+objectAnim+" no existe.");
								}
							}
							else
							{
								try
								{
									timelineLoop.insertMultiple( TweenMax.allFrom(objectsArr, duration, param, stagger), timeStart);
								}
								catch (error:Error)
								{
									trace("ERROR #04: Loop: Uno o más de los elementos "+objectsArr+" no existe.");
								}
							}
						}

					}
					//timelineLoop.play();
				}

			}

			for each (var buttonData:XML in scriptScreen.actions.action)
			{
				try
				{
					com.slurm.Button(getChildByName(buttonData. @ button)).addEventListener(MouseEvent.MOUSE_DOWN,onClickButton);
					com.slurm.Button(getChildByName(buttonData. @ button)).idScreen = Number(buttonData. @ screenId);
				}
				catch (error:Error)
				{
					trace("ERROR #06: El botón "+buttonData. @ button+" no existe.");
				}
			}
		}

		private function onClickButton(e:MouseEvent)
		{
			idNextScreen = e.currentTarget.idScreen;
			animExit();
		}

		public function animExit()
		{
			if (scriptScreen.endanim.object.length() > 0)
			{
				timelineEnd = new TimelineMax({onComplete:destroy,pause:true});
				for each (var objectData:XML in scriptScreen.endanim.object)
				{
					var objectAnim:String = objectData. @ name;
					var destination:String = objectData. @ destination;
					var duration:Number = Number(objectData. @ duration);
					var timeStart:Number = Number(objectData. @ timeStart);
					var multipleObjects:Boolean = false;
					var stagger:Number = Number(objectData. @ stagger);;
					var clip:DisplayObject;
					if (objectAnim.indexOf(","))
					{
						multipleObjects = true;
						var objectsNameArr = objectAnim.split(",");
						var objectsArr = [];
						for each (var objectName:String in objectsNameArr)
						{
							objectsArr.push(this.getChildByName(objectName));
						}
						clip = objectsArr[0];
					}
					else
					{
						clip = this.getChildByName(objectAnim);
					}
					var param:Object = createObjectParams(Utils.trim(objectData. @ params),clip);
					for each (var filterData:XML in objectData.filter)
					{
						param[filterData. @ type] = addFilters(Utils.trim(filterData. @ params));
					}
					if (destination == "to")
					{
						if (! multipleObjects)
						{
							try
							{
								timelineEnd.append( TweenMax.to(clip, duration, param) , timeStart );
							}
							catch (error:Error)
							{
								trace("ERROR #03: Animación Salida: El elemento "+objectAnim+" no existe.");
							}
						}
						else
						{
							try
							{
								timelineEnd.insertMultiple( TweenMax.allTo(objectsArr, duration, param, stagger), timeStart);
							}
							catch (error:Error)
							{
								trace("ERROR #04: Animación Salida: Uno o más de los elementos "+objectsArr+" no existe.");
							}
						}
					}
					else
					{
						if (! multipleObjects)
						{
							try
							{
								timelineEnd.append( TweenMax.from(clip, duration, param) , timeStart );
							}
							catch (error:Error)
							{
								trace("ERROR #03: Animación Salida: El elemento "+objectAnim+" no existe.");
							}
						}
						else
						{
							try
							{
								timelineEnd.insertMultiple( TweenMax.allFrom(objectsArr, duration, param, stagger), timeStart);
							}
							catch (error:Error)
							{
								trace("ERROR #04: Animación Salida: Uno o más de los elementos "+objectsArr+" no existe.");
							}
						}
					}

				}
				timelineEnd.play();
			}
			else
			{
				if (Number(scriptScreen.startanim. @ noRevert) != 1)
				{
					timelineStart.duration = Number(scriptScreen.startanim. @ timeRevert);
					timelineStart.reverse();
				}
				else
				{
					destroy();
				}
			}
		}

		public function destroy()
		{
			for (var i:uint = 0; i < this.numChildren; i++){
				var clip:DisplayObject = this.getChildAt(i);
				this.removeChild(clip);
				clip = null;
			}
			Core.instance.showScreen(idNextScreen);
		}

	}

}